#! /bin/bash
#variables globales
let milisegundos=0
let real
let sys
let user
#obtencion de milisegundos de una linea
#El primer parámetro es la cadena que contiene el tiempo codificado
#como xxmyys.
#Se retorna la cantidad de milisegundos indicados por la línea
function obtenerMilisegundos(){
	local cadena
	local cadenaAux
	local aux
	local pos
	cadena=$1
	miliSegundos=0
	pos=`expr index "$cadena" m`
	aux=`expr $pos - 1`
	cadenaAux=${cadena:0:aux}
	milisegundos=$cadenaAux
	milisegundos=`expr $milisegundos \* 60000`
	cadena=${cadena:pos}
	pos=`expr index "$cadena" .`
	aux=`expr $pos - 1`
	aux=${cadena:0:aux}
	aux=`expr $aux \* 1000`
	milisegundos=`expr $milisegundos + $aux`
	cadena=${cadena:pos}
	pos=`expr index "$cadena" s`
	aux=`expr $pos - 1`
	aux=${cadena:0:aux}
	milisegundos=`expr $milisegundos + $aux`
}	
#Se obtienen los tiempos de ordenamientos de c/archivo en milisegundos
function obtenerTiempos(){
	local linea
	local cadena
	local pos
	cadena=""
	linea=""
	while read linea
	do
		pos=`expr match "$linea" "real"`
		cero=0
		if [ $pos -ne $cero ]; then
			cadena=${linea:$pos}
			obtenerMilisegundos $cadena
			real=`expr $real + $milisegundos`
			
		else
			pos=`expr match "$linea" "user"`
			if [ $pos -ne $cero ]; then
				cadena=${linea:$pos}
				obtenerMilisegundos $cadena
				user=`expr $user + $milisegundos`
			else
				pos=`expr match "$linea" "sys"`
				if [ $pos -ne $cero ]; then
					cadena=${linea:$pos}
					obtenerMilisegundos $cadena
					sys=`expr $sys + $milisegundos`
				fi	
			fi
		fi
	done < "medicionIndividual.txt"
}
#Cálculo tiempos promedios de ordenamiento para 10 archivos aleatorios sin 
#ordenar
#Parametros:
# 1: tamaño en bytes
# 2: cantidad de muestras por archivo
# 3: tipo de ordenamiento -m o -s
function 10archivosAleatoriosSinOrdenar(){
	local tamanio
	local realTotal=0
	local sysTotal=0
	local userTotal=0
	local i
	local divisor
	local muestras
	local tipoOrd
	tamanio=$1
	muestras=$2
	tipoOrd=$3
	# 10 archivos
	echo "Promedio de tiempos para 10 archivos aleatorios sin ordenar de $tamanio bytes, por método $tipoOrd"
	echo "archivo 			 	real[ms]							user[ms]							sys[ms]"
	for i in {0..9} 
	do
		real=0
		sys=0
		user=0
		head -c $tamanio /dev/urandom >random.txt
		#Se toma una muestra de tamaño <muestras> para c/archivo
		for (( j=0; j<$muestras; j++ ))
		do
			echo -n "" >medicionIndividual.txt 
			echo -n "" >salida.txt
			time ./tp $tipoOrd random.txt >salida.txt 2>error.txt 
			obtenerTiempos
		done
		#Actualización suma total
		realTotal=`expr $real + $realTotal`
		sysTotal=`expr $sys + $sysTotal`
		userTotal=`expr $user + $userTotal`
		#Promedio Parcial
		real=`expr $real / $muestras`
		sys=`expr $sys / $muestras`
		user=`expr $user / $muestras`
		echo "$i 						$real									$user 									$sys"
	done
	#Promedio Total
	divisor=`expr $muestras \* 10`
	realTotal=`expr $realTotal / $divisor`
	sysTotal=`expr $sysTotal / $divisor`
	userTotal=`expr $userTotal / $divisor`
	echo "Promedio Total			$realTotal									$userTotal 									$sysTotal"
	echo ""
}
#Medir tiempos archivo ordenado
#Cálculo tiempos promedios de ordenamiento para un archivo aleatorio ordenado
#Parametros:
# 1: tamaño en bytes
# 2: cantidad de muestras por archivo
# 3: tipo de ordenamiento -m o -s
function tiempoArchivoOrdenado(){
	local tamanio
	local ruta
	local muestras
	local tipoOrd
	tamanio=$1
	muestras=$2
	tipoOrd=$3
	ruta="random.txt"
	#Un archivo ordenado
	echo "Promedio de tiempos para un archivo ordenado de $tamanio bytes, por método $tipoOrd"
	echo "real[ms]							user[ms]							sys[ms]"
	real=0
	sys=0
	user=0
	./tp -m random.txt >randomOrdenado.txt 2>error.txt 
	#Se toma una muestra de tamaño <muestras> para c/archivo
	for (( j=0; j<$muestras; j++ ))
	do 
		#Se toma una muestra de tamaño <muestras> para c/archivo
		echo -n "" > medicionIndividual.txt
		echo -n "" > salida.txt
		time ./tp $tipoOrd randomOrdenado.txt >salida.txt 2>error.txt 
		obtenerTiempos
	done
	#Promedio
	real=`expr $real / $muestras`
	sys=`expr $sys / $muestras`
	user=`expr $user / $muestras`
	echo "$real									$user 									$sys"
	echo ""
}
#Medir tiempos archivo ordenado inverso
#Cálculo tiempos promedios de ordenamiento para un archivo aleatorio ordenado inverso
#Parametros:
# 1: tamaño en bytes
# 2: cantidad de muestras por archivo
# 3: tipo de ordenamiento -m o -s
function tiempoArchivoOrdenadoInverso(){
	local tamanio
	local muestras
	local tipoOrd
	tamanio=$1
	muestras=$2
	tipoOrd=$3
	#Un archivo ordenado
	echo "Promedio de tiempos para un archivo con orden inverso de $tamanio bytes, por método $tipoOrd"
	echo "real[ms]							user[ms]							sys[ms]"
	real=0
	sys=0
	user=0
	./tp -i random.txt >randomInverso.txt
	#Se toma una muestra de tamaño <muestras> para c/archivo
	for (( j=0; j<$muestras; j++ ))
	do 
		echo -n "" >medicionIndividual.txt
		echo -n "" >salida.txt
		#Se toma una muestra de tamaño <muestras> para c/archivo
		time ./tp $tipoOrd randomInverso.txt >salida.txt 2>error.txt 
		obtenerTiempos
	done
	#Promedio
	real=`expr $real / $muestras`
	sys=`expr $sys / $muestras`
	user=`expr $user / $muestras`
	echo "$real									$user 									$sys"
	echo ""
}
#Prueba completa para un tamaño en bytes dado.
#Las pruebas consisten en tomar los tiempos promedios para un archivo ordenado,
#un archivo ordenado inverso y 10 archivos totalmente aleatorios.
#Parámetros:
# 1: tamaño en bytes
# 2: tamaño de las muestras para calcular promedios individuales.
# 3: método de ordenamiento a utilizar
# 4: tamaño de las muestras para el cálculo de tiempo de los archivos
#	 ordenados.
function tomarMediciones(){
	local tamanio
	local muestras
	local tipoOrd
	tamanio=$1
	muestras10=$2
	tipoOrd=$3
	muestrasOrd=$4	
	#Genero archivo random
	head -c $tamanio /dev/urandom >random.txt
	#Medir archivo ordenado
	tiempoArchivoOrdenado $tamanio $muestrasOrd $tipoOrd 
	#Medir archivo ordenado inverso
	tiempoArchivoOrdenadoInverso $tamanio $muestrasOrd $tipoOrd 
	#Medir 10 archivos
	10archivosAleatoriosSinOrdenar $tamanio $muestras10 $tipoOrd
}
#Programa Principal
#Parametros:
# 1: tamaño inicial en bytes 
# 2: tamaño final en bytes
# 3: tamaño de las muestras para calcular promedios de los 10 archivos
#    aleatorios.
# 4: tamaño de las muestras para el cálculo de tiempo de los archivos
#	 ordenados.
# 5: método de ordenamiento a utilizar

echo "Mediciones"
i=$1
final=$2
muestras10=$3
muestrasOrd=$4
metodoOrd=$5
while [ $i -le $final ]
do
	tomarMediciones $i $muestras10 $metodoOrd $muestrasOrd
	i=`expr $i \* 2`
done